package tech.waterism.controller;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import tech.waterism.constant.DispatchConstants;
import tech.waterism.document.DPrincipleCustomDocument;
import tech.waterism.dto.*;
import tech.waterism.service.DispatchService;
import tech.waterism.service.ForecastDispatchService;
import tech.waterism.utils.ApiResult;
import tech.waterism.utils.ForecastDispatchUtils;

import java.util.List;

@RestController
@RequestMapping(value = "/dispatch")
@Api(tags = "调度管理")
@Slf4j
@AllArgsConstructor
public class DispatchManageController {
    @Autowired
    private ForecastDispatchService forecastDispatchService;
    @Autowired
    private DispatchService dispatchService;

    @ApiOperation(value = "调洪演算")
    @PostMapping("/calculate")
    public ApiResult<List<TopoDataDto>> calculate(@RequestBody TopoDataDto dto) {
        try {
            // clear hydro info
            dto.setUuid(null);
            dto.setUseHydro(null);
            dto.getTopoObject().forEach(i -> i.setUseHydro(null));
            if (useDispatchRule(dto)) {
                // todo 改成异步
                return ApiResult.success(forecastDispatchService.calculateV2(dto));
            } else {
                return ApiResult.success(dispatchService.calculate(dto));
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ApiResult.failed(e.getMessage());
        }
    }

    /**
     * 调度规则里是否包含联调 -- 预报调度一体化bridge
     */
    private boolean useDispatchRule(TopoDataDto dto) {
        if (dto.getDispatchType() != null &&
                !dto.getDispatchType().equals(DispatchConstants.DISPATCH_PLAN_TYPE_DISPATCHRULES_CUSTOM)) {
            return false;
        }
        if (dto.getTopoObject().stream().allMatch(i -> i.getFpIndex().getPrincipleId() == null)) {
            return false;
        }
        for (TopoObjectDto topoObjectDto : dto.getTopoObject()) {
            FPIndexDto fpIndex = topoObjectDto.getFpIndex();
            String stcd = fpIndex.getStcd();
            if (fpIndex.getPrincipleId() == null) {
                continue;
            }
            DPrincipleCustomDocument principleCustomDocument;
            if (fpIndex.getPrincipleCustom() == null) {
                String principleId = fpIndex.getPrincipleId();
                principleCustomDocument = dPrincipleCustomService.getById(principleId);
            } else {
                principleCustomDocument = fpIndex.getPrincipleCustom();
            }
            if (ForecastDispatchUtils.useDispatchRule(principleCustomDocument, stcd)) {
                return true;
            }
        }
        return false;
    }
}
